/**
 * Copyright 2008 Mathias Doenitz, http://lis.to/
 *
 * This file is part of the lis.to java desktop client. The lis.to java desktop client is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * The lis.to java desktop client is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with the lis.to java desktop client.
 * If not, see http://www.gnu.org/licenses/
 */

package listo.client.dialogs;

import com.google.inject.Inject;
import listo.client.ImageProvider;
import listo.client.MainForm;
import listo.client.WindowState;
import listo.client.dialogs.controllers.*;
import listo.client.model.Task;
import listo.utils.reflection.Reflector;
import listo.utils.swing.CollapsiblePanel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TaskDialog extends BaseDialog<Task> implements CollapsiblePanel.CollapsedStateChangedListener {

    protected final WindowState windowState;
    private final ImageProvider imageProvider;
    private final TaskQuickEntryController quickEntryController;
    private final TaskDescController descController;
    private final TaskDueDateController dueDateController;
    private final TaskDueTimeController dueTimeController;
    private final TaskReminderController reminderController;
    private final TaskFoldersController foldersController;
    private final TaskClearTextController clearTextController;
    private final TaskNoteController noteController;

    protected JTextField descTextField;
    protected boolean quickEntryPanelCollapsed;
    protected boolean standardEntryPanelCollapsed;

    protected CollapsiblePanel quickEntryPanel;
    protected CollapsiblePanel standardEntryPanel;

    @Inject
    public TaskDialog(MainForm mainForm, ImageProvider imageProvider, Reflector reflector, WindowState windowState,
                      TaskQuickEntryController quickEntryController,
                      TaskDescController descController,
                      TaskDueDateController dueDateController,
                      TaskDueTimeController dueTimeController,
                      TaskReminderController reminderController,
                      TaskFoldersController foldersController,
                      TaskClearTextController clearTextController,
                      TaskNoteController noteController) {
        super(mainForm.isVisible() ? mainForm : null, imageProvider, reflector);
        this.imageProvider = imageProvider;
        this.windowState = windowState;
        this.quickEntryController = quickEntryController;
        this.descController = descController;
        this.dueDateController = dueDateController;
        this.dueTimeController = dueTimeController;
        this.reminderController = reminderController;
        this.foldersController = foldersController;
        this.clearTextController = clearTextController;
        this.noteController = noteController;

        switch (windowState.getTaskDialogState()) {
            case both:
                setPanelCollapsedState(false, false);
                break;
            case quick:
                setPanelCollapsedState(false, true);
                break;
            case standard:
                setPanelCollapsedState(true, false);
                break;
        }

        addWindowListener(new WindowAdapter() {
            public void windowClosed(WindowEvent e) {
                TaskDialog.this.windowState.setTaskDialogWidth(quickEntryPanel.getWidth());
            }
        });
    }

    public void setPanelCollapsedState(boolean quickEntryPanelCollapsed, boolean standardEntryPanelCollapsed) {
        this.quickEntryPanelCollapsed = quickEntryPanelCollapsed;
        this.standardEntryPanelCollapsed = standardEntryPanelCollapsed;
    }

    protected void onOk() {
        savePanelState();
        super.onOk();
    }

    public void cancel() {
        savePanelState();
        super.cancel();
    }

    private void savePanelState() {
        windowState.setTaskDialogState(quickEntryPanel.isCollapsed() ?
                standardEntryPanel.isCollapsed() ?
                        WindowState.TaskDialogState.both : WindowState.TaskDialogState.standard :
                standardEntryPanel.isCollapsed() ?
                        WindowState.TaskDialogState.quick : WindowState.TaskDialogState.both);
    }

    protected void createUI() {
        super.createUI();

        Icon collapsedIcon = imageProvider.getIcon("16x16/triangle_right.png");
        Icon expandedIcon = imageProvider.getIcon("16x16/triangle_down.png");

        quickEntryPanel = new CollapsiblePanel("Quick Entry", quickEntryPanelCollapsed, this, expandedIcon,
                collapsedIcon);
        JPanel quickEntryContent = new JPanel(new BorderLayout());
        JTextField quickEntryTextField = new JTextField();
        quickEntryContent.add(quickEntryTextField, BorderLayout.CENTER);
        quickEntryPanel.setContentPane(quickEntryContent);
        quickEntryPanel.getTitleLabel().setLabelFor(quickEntryTextField);
        attach(quickEntryTextField, quickEntryController);

        standardEntryPanel = new CollapsiblePanel("Standard Entry", standardEntryPanelCollapsed, this,
                expandedIcon, collapsedIcon);
        standardEntryPanel.setContentPane(createStandardEntryContent());

        CollapsiblePanel noteEntryPanel = new CollapsiblePanel("Attached Note", modelObject.getNote() == null, this,
                expandedIcon, collapsedIcon);
        JPanel noteEntryContent = new JPanel(new BorderLayout());
        JTextArea noteTextArea = new JTextArea() {
            public Dimension getPreferredSize() {
                Dimension dim = super.getPreferredSize();
                dim.height = Math.max(dim.height, 100);
                return dim;
            }
        };
        JScrollPane scrollPane = new JScrollPane(noteTextArea);
        noteEntryContent.add(scrollPane, BorderLayout.CENTER);
        noteEntryPanel.setContentPane(noteEntryContent);
        attach(noteTextArea, noteController);

        JPanel clearTextPanel = new JPanel(new BorderLayout());
        clearTextPanel.setBorder(BorderFactory.createTitledBorder("Clear Text"));
        final JEditorPane clearText = new JEditorPane();
        clearText.setEditable(false);
        clearText.setFocusable(false);
        clearText.setOpaque(false);
        clearText.setContentType("text/html");        

        scrollPane = new JScrollPane(clearText);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        clearTextPanel.add(scrollPane, BorderLayout.CENTER);
        attach(clearText, clearTextController);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int maxWidth = Math.max(windowState.getTaskDialogWidth(), screenSize.width - 50);
        createLayout(noteEntryPanel, clearTextPanel, maxWidth);

        setContentPane(contentPane);

        firstFocusComponent = !quickEntryPanelCollapsed ? quickEntryTextField :
                !standardEntryPanelCollapsed ? descTextField : noteTextArea;
    }

    protected void createLayout(CollapsiblePanel noteEntryPanel, JPanel clearTextPanel, int maxWidth) {
        layout.setHorizontalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING).
                        addComponent(quickEntryPanel, GroupLayout.DEFAULT_SIZE, windowState.getTaskDialogWidth(),
                                maxWidth).
                        addComponent(standardEntryPanel).
                        addComponent(noteEntryPanel).
                        addComponent(clearTextPanel).
                        addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().
                        addComponent(buttonOk).
                        addComponent(buttonCancel)));
        layout.setVerticalGroup(
                layout.createSequentialGroup().
                        addComponent(quickEntryPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
                                GroupLayout.PREFERRED_SIZE).
                        addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                        addComponent(standardEntryPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
                                GroupLayout.PREFERRED_SIZE).
                        addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                        addComponent(noteEntryPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, 400).
                        addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                        addComponent(clearTextPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
                                GroupLayout.PREFERRED_SIZE).
                        addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                        addGroup(layout.createParallelGroup().
                        addComponent(buttonOk).
                        addComponent(buttonCancel)));

        layout.linkSize(SwingConstants.HORIZONTAL, buttonOk, buttonCancel);
    }

    private JPanel createStandardEntryContent() {
        JPanel panel = new JPanel();

        JLabel descLabel = new JLabel("Description");
        descTextField = new JTextField();
        descLabel.setLabelFor(descTextField);
        attach(descTextField, descController);

        JLabel dueDateLabel = new JLabel("Due Date");
        JTextField dueDateTextField = new JTextField();
        dueDateLabel.setLabelFor(dueDateTextField);
        attach(dueDateTextField, dueDateController);

        JLabel dueTimeLabel = new JLabel("Due Time");
        JTextField dueTimeTextField = new JTextField();
        dueTimeLabel.setLabelFor(dueTimeTextField);
        attach(dueTimeTextField, dueTimeController);

        JLabel reminderLabel = new JLabel("Reminder");
        JTextField reminderTextField = new JTextField();
        reminderLabel.setLabelFor(reminderTextField);
        attach(reminderTextField, reminderController);

        JLabel foldersLabel = new JLabel("Folders");
        JTextField foldersTextField = new JTextField();
        foldersLabel.setLabelFor(foldersTextField);
        attach(foldersTextField, foldersController);

        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup().
                        addGroup(layout.createParallelGroup().
                                addComponent(descLabel).
                                addComponent(descTextField)).
                        addGroup(layout.createSequentialGroup().
                                addGroup(layout.createParallelGroup().
                                        addComponent(dueDateLabel).
                                        addComponent(dueDateTextField, 150, 150, 150)).
                                addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                                addGroup(layout.createParallelGroup().
                                        addComponent(dueTimeLabel).
                                        addComponent(dueTimeTextField, 100, 100, 100)).
                                addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                                addGroup(layout.createParallelGroup().
                                addComponent(reminderLabel).
                                addComponent(reminderTextField, 150, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))).
                        addGroup(layout.createParallelGroup().
                        addComponent(foldersLabel).
                        addComponent(foldersTextField)));

        layout.setVerticalGroup(
                layout.createSequentialGroup().
                        addGap(5).
                        addComponent(descLabel).
                        addComponent(descTextField).
                        addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                        addGroup(layout.createParallelGroup().
                                addComponent(dueDateLabel).
                                addComponent(dueTimeLabel).
                                addComponent(reminderLabel)).
                        addGroup(layout.createParallelGroup().
                                addComponent(dueDateTextField).
                                addComponent(dueTimeTextField).
                                addComponent(reminderTextField)).
                        addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).
                        addComponent(foldersLabel).
                        addComponent(foldersTextField));

        return panel;
    }

    public void collapsedStateChanged(CollapsiblePanel panel) {
        Dimension prefSize = getPreferredSize();
        setSize(getWidth(), prefSize.height);
    }

}